/*
 * com_flightmanager_utility_Encrypt.c
 *
 *  Created on: 2011-12-20
 *      Author: Steven
 */

#include <stdlib.h>
#include <stdio.h>
#include <md5.h>
#include <com_youknowme_utility_Encrypt.h>
#include <jni.h>
#include <android/log.h>
#include <verifysignpkg.h>

#define buffsize 2048

const int NO_ERROR = 0;

void jniThrowException(JNIEnv* env, const char* className, const char* msg) {
	jclass cls = (*env)->FindClass(env, className);
	/* if cls is NULL, an exception has already been thrown */
	if (cls != NULL) {
		(*env)->ThrowNew(env, cls, msg);
	}
	(*env)->DeleteLocalRef(env, cls);
}

void jniThrowNullPointerException(JNIEnv* env, const char* msg) {
	return jniThrowException(env, "java/lang/NullPointerException", msg);
}

jobject getFileResult_J(JNIEnv *env, jstring path, jstring destPath,
		jint errorcode) {
	jclass clazzEntryActivity = (*env)->FindClass(env,
			"com/youknowme/model/Result");
	jmethodID id_method = (*env)->GetMethodID(env, clazzEntryActivity, "<init>",
			"(Ljava/lang/String;Ljava/lang/String;I)V");

	jobject result = (*env)->NewObject(env, clazzEntryActivity, id_method, path,
			destPath, errorcode);
	(*env)->DeleteLocalRef(env, clazzEntryActivity);
	return result;
}

jobject getSuccessFileResult_C(JNIEnv *env, char* path, char* destPath) {
	return getFileResult_J(env, (*env)->NewStringUTF(env, path),
			(*env)->NewStringUTF(env, destPath), (jint) NO_ERROR);
}
jobject getSuccessFileResult_J(JNIEnv *env, jstring path, jstring destPath) {
	return getFileResult_J(env, path, destPath, (jint) NO_ERROR);
}

jobject getFileResult_C(JNIEnv *env, char* path, char* destPath,
		int errorcode) {
	return getFileResult_J(env, (*env)->NewStringUTF(env, path),
			(*env)->NewStringUTF(env, destPath), (jint) errorcode);
}

jobject getContext(JNIEnv *env, jobject encryptthis) {
	jclass clazzEntryActivity = (*env)->FindClass(env,
			"com/youknowme/utility/Encrypt");
	jfieldID fid = (*env)->GetFieldID(env, clazzEntryActivity, "context",
			"Landroid/content/Context;");

	jobject result = (*env)->GetObjectField(env, encryptthis, fid);

	(*env)->DeleteLocalRef(env, clazzEntryActivity);

	if (NULL == result) {
		jniThrowNullPointerException(env, "null context");
	}
	return result;
}
/*
 * Class:     com_youknowme_utility_Encrypt
 * Method:    encryFile
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/youknowme/utility/Encrypt/Result;
 */
JNIEXPORT jobject JNICALL Java_com_youknowme_utility_Encrypt_encryFile(
		JNIEnv *env, jobject thiz, jstring path, jstring destPath,
		jstring pwd) {
	jobject ctx = getContext(env, thiz);
	int verifyresult = verifyPackageName(env, ctx);
	if (verifyresult != 0) {
		//__android_log_write(ANDROID_LOG_ERROR,"tag","e1");
		//char* str = "package wrong";
		char* str = "";
		jstring tmpresult = (*env)->NewStringUTF(env, str);
		exit(0);
		return tmpresult;
	} else {
		//__android_log_write(ANDROID_LOG_DEBUG,"tag","r2");
	}

	verifyresult = verifySignature(env, ctx);
	if (verifyresult != 0) {
		//__android_log_write(ANDROID_LOG_ERROR,"tag","e3");
		//char* str = "signature wrong";
#ifndef ISDEBUG
		char* str = "";
		jstring tmpresult = (*env)->NewStringUTF(env, str);
		exit(0);
		return tmpresult;
#endif
	} else {
		//__android_log_write(ANDROID_LOG_DEBUG,"tag","r4");
	}
	(*env)->DeleteLocalRef(env, ctx);

	//judge file is exist

	return getSuccessFileResult_J(env, path, destPath);
}

/*
 * Class:     com_youknowme_utility_Encrypt
 * Method:    decryptFile
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/youknowme/utility/Encrypt/Result;
 */
JNIEXPORT jobject JNICALL Java_com_youknowme_utility_Encrypt_decryptFile(
		JNIEnv *env, jobject thiz, jstring path, jstring destPath,
		jstring pwd) {

	return getFileResult_J(env, path, destPath, 5);
	//return getSuccessFileResult_J(env, path, destPath);
}

/*
 * Class:     lilong
 * Method:    getEncryptString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_youknowme_utility_Encrypt_getEncryptString(
		JNIEnv *env, jobject thiz, jobjectArray params) {
	jobject ctx = getContext(env, thiz);
	int verifyresult = verifyPackageName(env, ctx);
	if (verifyresult != 0) {
		//__android_log_write(ANDROID_LOG_ERROR,"tag","e1");
		//char* str = "package wrong";
		char* str = "";
		jstring tmpresult = (*env)->NewStringUTF(env, str);
		exit(0);
		return tmpresult;
	} else {
		//__android_log_write(ANDROID_LOG_DEBUG,"tag","r2");
	}

	verifyresult = verifySignature(env, ctx);
	if (verifyresult != 0) {
		//__android_log_write(ANDROID_LOG_ERROR,"tag","e3");
		//char* str = "signature wrong";
#ifndef ISDEBUG
		char* str = "";
		jstring tmpresult = (*env)->NewStringUTF(env, str);
		exit(0);
		return tmpresult;
#endif
	} else {
		//__android_log_write(ANDROID_LOG_DEBUG,"tag","r4");
	}
	(*env)->DeleteLocalRef(env, ctx);

	char* str = "veryfy ok";
	jstring tmpresult = (*env)->NewStringUTF(env, str);
	return tmpresult;
	/*int len = 0;
	 char* joined = malloc(buffsize);
	 strcpy(joined, "");
	 
	 int size = (*env)->GetArrayLength(env, params);
	 int i = 0;
	 
	 for (i = 0; i < size; i++) {
	 jstring jparam = (jstring)(*env)->GetObjectArrayElement(env, params, i);
	 char* param = (char*)(*env)->GetStringUTFChars(env, jparam, NULL);
	 
	 //__android_log_write(ANDROID_LOG_DEBUG, "tag", param);
	 
	 strcat(joined, param);
	 len = len + strlen(param);
	 }
	 
	 strcat(joined, "&*^%@%$^#&");
	 len = len + 10;
	 joined[len] = '\0';
	 //__android_log_write(ANDROID_LOG_DEBUG, "tag", joined);
	 
	 char* md5 = MDString(joined);
	 char* result = malloc(9);
	 result[0] = md5[4];
	 result[1] = md5[1];
	 result[2] = md5[16];
	 result[3] = md5[9];
	 result[4] = md5[19];
	 result[5] = md5[30];
	 result[6] = md5[28];
	 result[7] = md5[22];
	 result[8] = '\0';
	 
	 jstring sid = (*env)->NewStringUTF(env, result);
	 
	 free(joined);
	 free(result);
	 
	 return sid;*/
}

/* This function will be call when the library first be loaded */
jint JNI_OnLoad(JavaVM* vm, void* reserved) {

	//获取JNI环境对象  
	JNIEnv* env = NULL;
	if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
		return JNI_ERR;
	}

	//应该检查包名和签名
	//initClazzMethodField(env);

	__android_log_write(ANDROID_LOG_DEBUG, "tag", "onloadxxxxx");

	return JNI_VERSION_1_4;
}

/* This function will be call when the library is released */
void JNI_OnUnload(JavaVM* vm, void* reserved) {
	__android_log_write(ANDROID_LOG_DEBUG, "tag", "onunload");
}

